#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

#include "oj_controller.hpp"
#include "oj_view.hpp"
#include "oj_model.hpp"
#include "user.hpp"

namespace ns_controller
{
    using namespace ns_view;
    using namespace ns_model;
    using namespace ns_user;

    class Controller
    {
    public:
        Controller() {}
        ~Controller() {}

        // 处理请求
        /**
         * @brief 处理HTTP请求
         * 
         * @param method HTTP请求方法（GET或POST）
         * @param path 请求路径
         * @param username 用户名
         * @param params 请求参数
         * @param html 用于存储生成的HTML内容的指针
         */
        void HandleRequest(const std::string& method, const std::string& path, const std::string& username, const std::unordered_map<std::string, std::string>& params, std::string* html)
        {
            if (method == "GET")
            {
                if (path == "/all_questions")
                {
                    // 调用AllQuestions函数处理所有问题的请求
                    this->AllQuestions(username, html);
                }
                else if (path == "/question")
                {
                    // 从参数中获取问题ID
                    int questionId = std::stoi(params.at("id"));
                    // 调用OneQuestion函数处理单个问题的请求
                    this->OneQuestion(username, questionId, html);
                }
                else if (path == "/add_question")
                {
                    // 显示添加问题页面
                    ShowAddQuestionPage(html);
                }
                else if (path == "/login")
                {
                    // 显示登录页面
                    ShowLoginPage(html);
                }
                else if (path == "/register")
                {
                    // 显示注册页面
                    ShowRegisterPage(html);
                }
                else
                {
                    // 处理其他GET请求
                    HandleOtherGetRequest(path, html);
                }
            }
            else if (method == "POST")
            {
                if (path == "/add_question")
                {
                    // 从参数中获取问题标题、描述和难度
                    std::string title = params.at("title");
                    std::string description = params.at("description");
                    std::string difficulty = params.at("difficulty");
                    // 调用AddQuestion函数处理添加问题的请求
                    AddQuestion(username, title, description, difficulty, html);
                }
                else if (path == "/login")
                {
                    // 从参数中获取用户名和密码
                    std::string username = params.at("username");
                    std::string password = params.at("password");
                    // 调用Login函数处理登录请求
                    if (userService_.Login(username, password))
                    {
                        // 登录成功，重定向到所有问题页面
                        RedirectToAllQuestionsPage(html);
                    }
                    else
                    {
                        // 登录失败，显示错误信息
                        ShowErrorMessage("Login failed. Invalid username or password.", html);
                    }
                }
                else if (path == "/register")
                {
                    // 从参数中获取用户名和密码
                    std::string username = params.at("username");
                    std::string password = params.at("password");
                    // 调用Register函数处理注册请求
                    if (userService_.Register(username, password))
                    {
                        // 注册成功，重定向到登录页面
                        RedirectToLoginPage(html);
                    }
                    else
                    {
                        // 注册失败，显示错误信息
                        ShowErrorMessage("Registration failed. Username already exists.", html);
                    }
                }
                else
                {
                    // 处理其他POST请求
                    HandleOtherPostRequest(path, params, html);
                }
            }
            else
            {
                // 处理其他HTTP方法
                HandleOtherMethod(method, html);
            }
        }

    private:
        Model model_;
        View view_;
        UserService userService_;

        // 显示添加问题页面
        void ShowAddQuestionPage(std::string* html)
        {
            std::string src_html = template_path + "add_question.html";
            ctemplate::Template *tpl = ctemplate::Template::GetTemplate(src_html, ctemplate::DO_NOT_STRIP);
            tpl->Expand(html, nullptr);
        }

        // 显示登录页面
        void ShowLoginPage(std::string* html)
        {
            std::string src_html = template_path + "login.html";
            ctemplate::Template *tpl = ctemplate::Template::GetTemplate(src_html, ctemplate::DO_NOT_STRIP);
            tpl->Expand(html, nullptr);
        }

        // 显示注册页面
        void ShowRegisterPage(std::string* html)
        {
            std::string src_html = template_path + "register.html";
            ctemplate::Template *tpl = ctemplate::Template::GetTemplate(src_html, ctemplate::DO_NOT_STRIP);
            tpl->Expand(html, nullptr);
        }

        // 处理其他GET请求
        void HandleOtherGetRequest(const std::string& path, std::string* html)
        {
            // 在这里处理其他GET请求
            *html = "404 Not Found";
        }

        // 处理其他POST请求
        void HandleOtherPostRequest(const std::string& path, const std::unordered_map<std::string, std::string>& params, std::string* html)
        {
            // 在这里处理其他POST请求
            *html = "404 Not Found";
        }

        // 处理其他HTTP方法
        void HandleOtherMethod(const std::string& method, std::string* html)
        {
            // 在这里处理其他HTTP方法
            *html = "405 Method Not Allowed";
        }

        // 重定向到所有问题页面
        void RedirectToAllQuestionsPage(std::string* html)
        {
            *html = "HTTP/1.1 302 Found\r\nLocation: /all_questions\r\n\r\n";
        }

        // 重定向到登录页面
        void RedirectToLoginPage(std::string* html)
        {
            *html = "HTTP/1.1 302 Found\r\nLocation: /login\r\n\r\n";
        }

        // 显示错误信息
        void ShowErrorMessage(const std::string& message, std::string* html)
        {
            std::string src_html = template_path + "error.html";
            ctemplate::Template *tpl = ctemplate::Template::GetTemplate(src_html, ctemplate::DO_NOT_STRIP);
            tpl->SetValue("ERROR_MESSAGE", message);
            tpl->Expand(html, nullptr);
        }
    };
} // namespace ns_controller
